package com.lemurian.bankdata.action.business;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.validation.SkipValidation;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;

import com.lemurian.bankdata.dto.LogHelper;
import com.lemurian.bankdata.lite.authentication.BankDataPrincipal;
import com.lemurian.bankdata.lite.enums.UserActivityType;
import com.lemurian.bankdata.lite.logger.BankDataLogger;
import com.lemurian.bankdata.lite.struts.Pager;
import com.lemurian.bankdata.lite.struts.PartialList;
import com.lemurian.bankdata.lite.utils.GeneralConstant;
import com.lemurian.bankdata.lite.utils.GlobalFunction;
import com.lemurian.bankdata.services.ActivityLogService;
import com.lemurian.bankdata.services.TaxService;
import com.lemurian.bankdata.utils.BaseAction;
import com.lemurian.entity.Tax;
import com.lemurian.entity.User;
import com.opensymphony.xwork2.Preparable;

@SuppressWarnings("serial")
public class PajakAction extends BaseAction implements Preparable {

	private BankDataLogger log = BankDataLogger.getLogger(PajakAction.class.getSimpleName());
	
	/*private Client klien = new Client();
	private List<Client> listKlien;*/
	private String namaDebitur = "";
	private String nominalPajakSSB = "";
	private String nominalPajakSSP = "";
	private Boolean sudahBayar;
	private Boolean bayarKeKantor;
	private String tanggalPembayaran = "";
	
	private Tax pajak;
	private List<Tax> listPajak;
	
	private int id = 0;
	
	private User user;
	private BankDataPrincipal principal;
	
	private String[] selectedRows;
	
	private String message = "";

	private DateFormat df = new SimpleDateFormat("dd-MM-yyyy");
	
	@Autowired private TaxService pajakService;
	
	@Autowired 
	private ActivityLogService userActivityLogService;
	private LogHelper userActivityLog;
	
	@Override
	public void prepare() throws Exception {
		principal = (BankDataPrincipal) getSession().get(GeneralConstant.USER_PRINCIPAL);
		user = principal.getUser();
		log.sInfo("got pajak id [%s]", id);
        if (id > 0) {
            pajak = pajakService.findById(id);
        	/*if (pajak != null) {
        		log.sInfo("got tax with id [%s]", pajak.getId());
            }*/
        }
	}

	@Override
	@SkipValidation
	public String list() {
		log.info("list pajak");
		setPreviousPage(GeneralConstant.LIST);
		try {
			log.sInfo("Filter Nama Debitur [%s]", namaDebitur);
			log.sInfo("Filter Sudah Bayar ?   [%s]", sudahBayar);
			PartialList<Tax> partialList = pajakService.findByCriteria(getStart(), getCount(),
					getAscDesc().equalsIgnoreCase("desc") ? Order.desc(getOrderBy().length() > 0 ? getOrderBy() : "paymentDate") : Order.asc(getOrderBy().length() > 0 ? getOrderBy() : "paymentDate"),
					namaDebitur != null && !namaDebitur.equalsIgnoreCase("") ? Restrictions.ilike("debitur.name", namaDebitur, MatchMode.ANYWHERE) : Restrictions.ne("id", new Integer(-1)),
                    sudahBayar != null ? Restrictions.eq("paymentStatus", sudahBayar) : Restrictions.ne("id", new Integer(-1))
                    );

            listPajak = partialList.getList();
            log.sInfo("found [%s] pajak", listPajak.size());
            
            setPager(Pager.generatePager(getStart(), getCount(), partialList.getTotal()));
            setPagerItem(Pager.generatePagerItem(getStart(), getCount(), partialList.getTotal()));

            partialList = null;

		} catch (Exception e) {
			e.printStackTrace();
		}
        setMappedRequest(GeneralConstant.LIST);
        return SUCCESS;

	}

	@Override
	@SkipValidation
	public String add() {
		try {
		
			log.info("on pajak form");
			nominalPajakSSB = pajak.getNominalSSB() != null ? pajak.getNominalSSB().toString() : "";
			nominalPajakSSP = pajak.getNominalSSP() != null ? pajak.getNominalSSP().toString() : "";
			sudahBayar = pajak.getPaymentStatus() != null ? pajak.getPaymentStatus() : false;
			bayarKeKantor = pajak.getPaymentTaxStatus() != null ? pajak.getPaymentTaxStatus() : false;
			if (pajak.getPaymentDate() != null) {
				tanggalPembayaran = df.format(pajak.getPaymentDate());	
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		setMappedRequest(GeneralConstant.SAVE);
        setPreviousPage(GeneralConstant.ADD);
        return SUCCESS;
	}

	public String sudahBayar() {
		try {
			if (selectedRows == null || selectedRows.length == 0) {
				addCustomActionWarning("Maaf, tidak ada klien yang dipilih");

				setMappedRequestFullPath("/PajakAction_list.do");
				return GeneralConstant.REDIRECT;
			}
			log.sInfo("Total Checked [%s]", selectedRows.length);
			for (int i = 0; i < selectedRows.length; i++) {
				log.sInfo("Pajak ID [%s]", selectedRows[i]);
				int pajakId = Integer.parseInt(GlobalFunction.decodeParameter(selectedRows[i]));
				pajak = pajakService.findById(pajakId);
				if (pajak != null) {
					log.sInfo("Pajak Record was found [%s]", pajak.getId());
				} else {
					// Harusnya ga mungkin
					log.info("init new object <-- harusnya ga mungkin");
					pajak = new Tax();
				}
				pajak.setPaymentStatus(true);
				pajak.setUpdateDate(new Timestamp(System.currentTimeMillis()));
				try {
					pajakService.save(pajak);
					
					userActivityLog = new LogHelper(user, UserActivityType.EDIT_SUDAH_BAYAR_PAJAK);
					
		            try {
		                log.sInfo(" :: User [%s:%s] is successfully updated tax status of [%s] that taxes have been paid on tax office", user.getId(), user.getName(), pajak.getClient().getDebitur().getName());

		                //check if activity is success
		                userActivityLog.setStatus(LogHelper.SUCCESS_ACTIVITY);
		            } catch (Exception e) {
		                log.sInfo(" :: Error was raised when User [%s:%s] delegate updated tax status of [%s] that taxes have been paid on tax office", user.getId(), user.getName(), pajak.getClient().getDebitur().getName());
		                
		                //set activity log status into failed
		                userActivityLog.setStatus(LogHelper.FAILED_ACTIVITY);
		                userActivityLog.setErrorMsg(e.getMessage());
		            }
		            //save activity log
		            userActivityLog.setSessionId(ServletActionContext.getRequest().getSession().getId());
		            userActivityLog.getAdditionalParams().add(pajak.getClient().getDebitur().getName());
		            userActivityLogService.saveUserActivity(userActivityLog);
				} catch (Exception e) {
					e.printStackTrace();
				    message = "Maaf terjadi kesalahan, message : "+e.getMessage();
		            addCustomActionError(message);
		    		setMappedRequestFullPath("/PajakAction_list.do");
		    		return GeneralConstant.REDIRECT;
				}
				message = "Data klien berhasil diubah dengan sukses";
	            addCustomActionMessage(message);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		setMappedRequestFullPath("/PajakAction_list.do");
		return GeneralConstant.REDIRECT;
	}

	public String bayarKeKantor() {
		try {
			if (selectedRows == null || selectedRows.length == 0) {
				addCustomActionWarning("Maaf, tidak ada klien yang dipilih");
				setMappedRequestFullPath("/PajakAction_list.do");
				return GeneralConstant.REDIRECT;
			}
			log.sInfo("Total Checked [%s]", selectedRows.length);
			for (int i = 0; i < selectedRows.length; i++) {
				log.sInfo("Pajak ID [%s]", selectedRows[i]);
				int pajakId = Integer.parseInt(GlobalFunction.decodeParameter(selectedRows[i]));
				pajak = pajakService.findById(pajakId);
				if (pajak != null) {
					log.sInfo("Pajak Record was found [%s]", pajak.getId());
				} else {
					// Harusnya ga mungkin
					log.info("init new object <-- harusnya ga mungkin");
					pajak = new Tax();
				}
				pajak.setPaymentTaxStatus(true);
				pajak.setUpdateDate(new Timestamp(System.currentTimeMillis()));
				try {
					pajakService.save(pajak);
					
					userActivityLog = new LogHelper(user, UserActivityType.EDIT_SUDAH_BAYAR_KE_KANTOR_PAJAK);
					
		            try {
		                log.sInfo(" :: User [%s:%s] is successfully updated tax status of [%s] that taxes have been paid on tax office", user.getId(), user.getName(), pajak.getClient().getDebitur().getName());

		                //check if activity is success
		                userActivityLog.setStatus(LogHelper.SUCCESS_ACTIVITY);
		            } catch (Exception e) {
		                log.sInfo(" :: Error was raised when User [%s:%s] delegate updated tax status of [%s] that taxes have been paid on tax office", user.getId(), user.getName(), pajak.getClient().getDebitur().getName());
		                
		                //set activity log status into failed
		                userActivityLog.setStatus(LogHelper.FAILED_ACTIVITY);
		                userActivityLog.setErrorMsg(e.getMessage());
		            }
		            //save activity log
		            userActivityLog.setSessionId(ServletActionContext.getRequest().getSession().getId());
		            userActivityLog.getAdditionalParams().add(pajak.getClient().getDebitur().getName());
		            userActivityLogService.saveUserActivity(userActivityLog);
				} catch (Exception e) {
					e.printStackTrace();
				    message = "Maaf terjadi kesalahan, message : "+e.getMessage();
		            addCustomActionError(message);
		            setMappedRequestFullPath("/PajakAction_list.do");
					return GeneralConstant.REDIRECT;
				}
				message = "Data klien berhasil diubah dengan sukses";
				addCustomActionMessage(message);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		setMappedRequestFullPath("/PajakAction_list.do");
		return GeneralConstant.REDIRECT;
	}
	
	@Override
	public String save() {
		log.info("simpan konfigurasi pajak");
			
		try {
			
			if(id > 0) {
				log.sInfo("Nominal SSB        [%s]", nominalPajakSSB);
				log.sInfo("Nominal SSP        [%s]", nominalPajakSSP);
				log.sInfo("Sudah Bayar        [%s]", sudahBayar);
				log.sInfo("Bayar ke Kantor	  [%s]", bayarKeKantor);
				log.sInfo("Tanggal Pembayaran [%s]", tanggalPembayaran);
				
				
				pajak.setUpdateBy(user.getName());
				pajak.setUpdateDate(new Timestamp(System.currentTimeMillis()));
				
				pajak.setNominalSSB(BigDecimal.valueOf(Double.valueOf(nominalPajakSSB)));
				pajak.setNominalSSP(BigDecimal.valueOf(Double.valueOf(nominalPajakSSP)));
				pajak.setPaymentStatus(sudahBayar);
				pajak.setPaymentTaxStatus(bayarKeKantor);
				if (tanggalPembayaran != null && tanggalPembayaran.length() != 0) {
					pajak.setPaymentDate(df.parse(tanggalPembayaran));
				} else {
					pajak.setPaymentDate(null);
				}
				try {
					pajakService.save(pajak);
					
					userActivityLog = new LogHelper(user, UserActivityType.EDIT_STATUS_PAJAK);
					
		            try {
		                log.sInfo(" :: User [%s:%s] is successfully updated tax status of [%s]", user.getId(), user.getName(), pajak.getClient().getDebitur().getName());

		                //check if activity is success
		                userActivityLog.setStatus(LogHelper.SUCCESS_ACTIVITY);
		            } catch (Exception e) {
		                log.sInfo(" :: Error was raised when User [%s:%s] updated tax status of [%s]", user.getId(), user.getName(), pajak.getClient().getDebitur().getName());
		                
		                //set activity log status into failed
		                userActivityLog.setStatus(LogHelper.FAILED_ACTIVITY);
		                userActivityLog.setErrorMsg(e.getMessage());
		            }
		            //save activity log
		            userActivityLog.setSessionId(ServletActionContext.getRequest().getSession().getId());
		            userActivityLog.getAdditionalParams().add(pajak.getClient().getDebitur().getName());
		            userActivityLogService.saveUserActivity(userActivityLog);
				} catch (Exception e) {
					e.printStackTrace();
				    message += "Maaf terjadi kesalahan, message : "+e.getMessage();
				    addCustomActionMessage(message);
					setMappedRequestFullPath("/PajakAction_list.do");
					return GeneralConstant.REDIRECT;
				}
				message += "Data klien berhasil disimpan";
				addCustomActionMessage(message);
			} else {
				addCustomActionError("Maaf terjadi kesalahan, message : ID Pajak = 0");
				setMappedRequestFullPath("/PajakAction_list.do");
				return GeneralConstant.REDIRECT;
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		    message += "Maaf terjadi kesalahan, message : "+e.getMessage();
            addCustomActionError(message);
		}
		setMappedRequestFullPath("/PajakAction_list.do");
		return GeneralConstant.REDIRECT;
	}
	
	@Override
	@SkipValidation
	public String edit() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String update() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	@SkipValidation
	public String detail() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	@SkipValidation
	public String delete() {
		// TODO Auto-generated method stub
		return null;
	}

	public int getId() {
		return id;
	}

	public void setId(String id) {
		int id_ = 0;
		if(id != null && !id.equalsIgnoreCase("0")) {
			id = GlobalFunction.decodeParameter(id);
	        id_ = Integer.parseInt(id);
		}
        this.id = id_;
	}

	public String[] getSelectedRows() {
		return selectedRows;
	}

	public void setSelectedRows(String[] selectedRows) {
		this.selectedRows = selectedRows;
	}
	
	public Tax getPajak() {
		return pajak;
	}

	public void setPajak(Tax pajak) {
		this.pajak = pajak;
	}

	public List<Tax> getListPajak() {
		return listPajak;
	}

	public void setListPajak(List<Tax> listPajak) {
		this.listPajak = listPajak;
	}

	public Boolean getSudahBayar() {
		return sudahBayar;
	}

	public void setSudahBayar(Boolean sudahBayar) {
		this.sudahBayar = sudahBayar;
	}

	public void setId(int id) {
		this.id = id;
	}

	public Boolean getBayarKeKantor() {
		return bayarKeKantor;
	}

	public void setBayarKeKantor(Boolean bayarKeKantor) {
		this.bayarKeKantor = bayarKeKantor;
	}

	public String getTanggalPembayaran() {
		return tanggalPembayaran;
	}

	public void setTanggalPembayaran(String tanggalPembayaran) {
		this.tanggalPembayaran = tanggalPembayaran;
	}

	public String getNominalPajakSSP() {
		return nominalPajakSSP;
	}

	public void setNominalPajakSSP(String nominalPajakSSP) {
		this.nominalPajakSSP = nominalPajakSSP;
	}

	public String getNominalPajakSSB() {
		return nominalPajakSSB;
	}

	public void setNominalPajakSSB(String nominalPajakSSB) {
		this.nominalPajakSSB = nominalPajakSSB;
	}

	public String getNamaDebitur() {
		return namaDebitur;
	}

	public void setNamaDebitur(String namaDebitur) {
		this.namaDebitur = namaDebitur;
	}

}
